to do before publish

#change all path to data showing my environment (NAS...) mettre lien à partir de Workspace ou il dowloaderont les fichier source (fastq et objet R)
#ajouter un test pour etre sur que y'ai subset 1 et 2 et pas que un des deux 

#do we want to show the code in rmd ? 

# GO mise en ligne des fichier brut

#test final sans aucun objet, avec le premier obj et avec le deuxieme

#change output path

[1] “You are starting the analysis from count matrix obtain with CellRanger and Cite-seq-count”

Loading the first experiment

Looking to HTO distribution accross sample :

#HTO distribution
par(mfrow=c(1,1))
par(las=2)
par(mar=c(5,15,3,3))
barplot(rowSums(hto1), main = "sequenced HTO distribution", horiz=TRUE)

rowSums(hto1)
##   Spleen-MP    Spleen-M Spleen-ctrl    Spleen-P   Thymus-MP    Thymus-M 
##      688432      206663      265412      662165      196262      117402 
## Thymus-ctrl    Thymus-P 
##      156856      562594

Demultiplexing HTO

Demultiplexing results

Cells classification

print (table(hashtag1@meta.data$MULTI_ID))
## 
##     Doublet    Negative Spleen-ctrl    Spleen-M   Spleen-MP    Spleen-P 
##         307          69         438         255         710         609 
## Thymus-ctrl    Thymus-M   Thymus-MP    Thymus-P 
##         325         245         294         935

Violinplot (features)

VlnPlot(hashtag1,features = c("nFeature_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

Violinplot (HTO counts)

VlnPlot(hashtag1,features = c("nCount_HTO"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

tSNEs based on HTO

# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = hashtag1, assay = "HTO"))))

# Calculate tSNE embeddings with a distance matrix
hashtag1 <- RunTSNE(hashtag1, distance.matrix = hto.dist.mtx, perplexity = 100)

HTO margin

Tsne<-data.frame(
  tSNE_1 = hashtag1@reductions$tsne@cell.embeddings[,1],
  tSNE_2= hashtag1@reductions$tsne@cell.embeddings[,2],
  gene= hashtag1@meta.data$HTO_margin
)

HTO= hashtag1@meta.data$MULTI_ID
Max=max(hashtag1@meta.data$HTO_margin)
Min=min(hashtag1@meta.data$HTO_margin)
ggplot(Tsne,aes(x=tSNE_1,y=tSNE_2))+geom_point(aes(color=gene,shape=HTO))+
           scale_colour_gradient2(low = "blue",mid="orange",high="red",name="HTO margin",midpoint=(Max+Min)/2)+scale_shape_manual(values = c(15,16,17,18,19,20,21,22,23,24,25))

Ridge plots

Visualize enrichment for selected HTOs with ridge plots

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[1:2],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[3:4],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[5:6],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[7:8],ncol = 2, group.by = "MULTI_ID")

Sample Information

The analysis will be run on the sample 1 (181031).

During the sample loading, we filter cells that do not pass the following filters.
Here are the description of those parameters in the Seurat CreateSeuratObject function:

  • min.genes: Include cells where at least 200 genes are detected
  • min.cells: Include genes with detected expression in at least 3 cells

After those filters, the remaining cell number is `r length(colnames(hashtag1@assays$RNA@data)).

#add Exp1 cell identity
HTO_cr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-ctrl" ))
HTO_ct1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-ctrl" ))
HTO_mr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-M" ))
HTO_mt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-M" ))
HTO_pr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-P" ))
HTO_pt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-P" ))
HTO_pmr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-MP" ))
HTO_pmt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-MP" ))
HTO_d1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Doublet" ))
HTO_n1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Negative" ))

HTO_thymus1 = c(HTO_ct1,HTO_mt1,HTO_pt1,HTO_pmt1)
HTO_spleen1 = c(HTO_cr1,HTO_mr1,HTO_pr1,HTO_pmr1)
HTO_identified1 = c(HTO_thymus1, HTO_spleen1)


# Create a Seurat object without doublet and unassigned cells (remove "negative", "doublet" & "nothing"))
clean.subset1 <- subset(x = hashtag1, cells = HTO_identified1)
VlnPlot(clean.subset1,features = c("nFeature_RNA", "nCount_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

After removing doublets and negative cells, the remaining cell number is `r length(colnames(clean.subset1@assays$RNA@data)).

Mitochondrial percentage versus nFeatures

df<-data.frame(multi.id=Seurat1@misc$old_meta_data$MULTI_ID,percent.mito=Seurat1@misc$old_meta_data$percent.mito,nFeature_RNA=Seurat1@misc$old_meta_data$nFeature_RNA)
ggplotly(ggplot(df,aes(x=nFeature_RNA,y=percent.mito,color=multi.id))+geom_point())

UMAP

ggplotly(DimPlot(Seurat1, reduction = "umap", group.by = "MULTI_ID", do.label = TRUE, pt.size = 1))

Loading the second experiment

par(mfrow=c(1,1))
par(las=2)
par(mar=c(5,15,3,3))
barplot(rowSums(hto2), main = "sequenced HTO distribution", horiz=TRUE)

rowSums(hto2)
##   Spleen-MP    Spleen-M Spleen-ctrl    Spleen-P   Thymus-MP    Thymus-M 
##     3569690     1668124      929963     3251282      484276      749822 
## Thymus-ctrl    Thymus-P 
##      310711     1203239

Demultiplexing results

Cells classification

print (table(hashtag2@meta.data$MULTI_ID))
## 
##     Doublet    Negative Spleen-ctrl    Spleen-M   Spleen-MP    Spleen-P 
##        2254         427         824        1294        2589        1689 
## Thymus-ctrl    Thymus-M   Thymus-MP    Thymus-P 
##         461        1266         522        1664

Violinplot (features)

VlnPlot(hashtag2,features = c("nFeature_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

Violin plots (HTO counts)

VlnPlot(hashtag2,features = c("nCount_HTO"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

tSNEs based on HTO

# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = hashtag2, assay = "HTO"))))

# Calculate tSNE embeddings with a distance matrix
hashtag2 <- RunTSNE(hashtag2, distance.matrix = hto.dist.mtx, perplexity = 100)
DimPlot(hashtag2, group.by = "MULTI_ID")

HTO margin

Tsne<-data.frame(
  tSNE_1 = hashtag2@reductions$tsne@cell.embeddings[,1],
  tSNE_2= hashtag2@reductions$tsne@cell.embeddings[,2],
  gene= hashtag2@meta.data$HTO_margin
)

HTO= hashtag2@meta.data$MULTI_ID
Max=max(hashtag2@meta.data$HTO_margin)
Min=min(hashtag2@meta.data$HTO_margin)

ggplot(Tsne,aes(x=tSNE_1,y=tSNE_2))+geom_point(aes(color=gene,shape=HTO))+
           scale_colour_gradient2(low = "blue",mid="orange",high="red",name="HTO margin",midpoint=(Max+Min)/2)+scale_shape_manual(values = c(15,16,17,18,19,20,21,22,23,24,25))

Ridge plots

Visualize enrichment for selected HTOs with ridge plots

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[1:2],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[3:4],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[5:6],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[7:8],ncol = 2, group.by = "MULTI_ID")

Sample Information

The analysis will be run on the sample 2 (190211).

During the sample loading, we filter cells that do not pass the following filters.

Used parameters in the Seurat CreateSeuratObject function: * min.genes: 3 . Include cells where at least 3 genes are detected * min.cells: 200 . Include genes with detected expression in at least 200 cells

After those filters, the remaining cell number is `r length(colnames(hashtag2@assays$RNA@data)).

#add Exp2 cell identity
HTO_cr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID == "Spleen-ctrl" ))
HTO_ct2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-ctrl" ))
HTO_mr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-M" ))
HTO_mt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-M" ))
HTO_pr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-P" ))
HTO_pt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-P" ))
HTO_pmr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-MP" ))
HTO_pmt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-MP" ))
HTO_d2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Doublet" ))
HTO_n2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Negative" ))

HTO_thymus2 = c(HTO_ct2,HTO_mt2,HTO_pt2,HTO_pmt2)
HTO_spleen2 = c(HTO_cr2,HTO_mr2,HTO_pr2,HTO_pmr2)
HTO_identified2 = c(HTO_thymus2, HTO_spleen2)

# Create a Seurat object without doublet and unassigned cells (remove "negative", "doublet" & "nothing"))
clean.subset2 <- subset(x = hashtag2, cells = HTO_identified2)
VlnPlot(clean.subset2,features = c("nFeature_RNA", "nCount_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

After removing doublets and negative cells, the remaining cell number is `r length(colnames(clean.subset2@assays$RNA@data)).

Adding ADT

# Load in the UMI matrix
umi <- GetAssayData(object = clean.subset2, slot = "counts")

# Load in the ADT count matrix
raw.adt <- Read10X(PATH_ADT_DATA2, gene.column = 1)
adt <- raw.adt[c(1:6),]

rownames(adt) <- c("CD4","CD5","CD8","CD25","CD44","CD69")

#create an empty matrix containing NAs
Cell.list <- colnames(GetAssayData(object = clean.subset2[["RNA"]], slot = "data" ) )
ADT.list <- c(unique(rownames(adt)))
mat.adt <- matrix(nrow = length(ADT.list), ncol = length(Cell.list))
rownames(mat.adt) = ADT.list
colnames(mat.adt) = Cell.list

# Get cell barcodes detected by both RNA and ADT
joint_bcs <- intersect(colnames(umi),colnames(adt))
adt <- as.matrix(adt[,joint_bcs])

# Fill the empty matrix with values when existing
mat.adt[,joint_bcs]<-adt[,joint_bcs]

# Add ADT data as a new assay independent from RNA
clean.subset2[["ADT"]] <- CreateAssayObject(counts = mat.adt[,colnames(clean.subset2)])

# Normalize ADT data, here we use centered log-ratio (CLR) transformation
clean.subset2 <- NormalizeData(clean.subset2, assay = "ADT", normalization.method = "CLR")

#Scale
clean.subset2 <- ScaleData(clean.subset2, assay = "ADT")

ADT list :

print (rownames(adt))

[1] “CD4” “CD5” “CD8” “CD25” “CD44” “CD69”

Mitochondrial percentage versus nFeatures

df<-data.frame(multi.id=Seurat2@misc$old_meta_data$MULTI_ID,percent.mito=Seurat2@misc$old_meta_data$percent.mito,nFeature_RNA=Seurat2@misc$old_meta_data$nFeature_RNA)
ggplotly(ggplot(df,aes(x=nFeature_RNA,y=percent.mito,color=multi.id))+geom_point())

UMAP:

ggplotly(DimPlot(Seurat2, reduction = "umap", group.by = "MULTI_ID", do.label = TRUE, pt.size = 1))

Merging our two experiments

Load separate R object

You can load objects done with the code above. Or our object ?? (link )

Integrating the 2 seurat objects with seurat integration (cca)

We identified r length(gene1) expressed in sample1 and r length(gene2) expressed in sample2. r length(common_genes) are in common in this two set and will the integrated in the merged and corrected object.

UMAP:

Analysis part

Sample Information

The analysis will be run on the sample MYC_PTEN_01 (181031 & 190211).

During the sample loading, we filter cells that do not pass the following filters. We also filter cells that are detected as human/mouse multiplet using their barcodes.
Here are the description of those parameters in the Seurat CreateSeuratObject function:

  • min.genes: Include cells where at least this many genes are detected
  • min.cells: Include genes with detected expression in at least this many cells

After those filters, and merging MYC_PTEN_01 and MYC_PTEN02 the remaining cell number is r length(colnames(exp1.2.integrated)).

UMAP and clustering parameter

Merge checking

HTO

Orig.idents

T-cell selection

According to T-cell markers we will exclude Cd3d low clusters: 13 (Bcells), 11, 14, 17 (monocytes/macrophages). According to T-cell markers we will exclude Cd3d/Cd3e low clusters: 11 (Bcells), 13, 17, 18, 19 (monocytes/macrophages), 16, 14 (ILC/NK).

Known RNA B and T markers

re clustering

T-cell umaps

HTO

clustering

END OF PREPROCESSING

We obtain the final object with clustering to start the analysis

sessionInfo()
## R version 3.5.3 (2019-03-11)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
## 
## Matrix products: default
## BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.18.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] knitr_1.23         RColorBrewer_1.1-2 magrittr_1.5      
## [4] dplyr_0.8.1        gridExtra_2.3      kableExtra_1.1.0  
## [7] plotly_4.9.0       ggplot2_3.1.1      Seurat_3.0.1      
## 
## loaded via a namespace (and not attached):
##   [1] nlme_3.1-140        tsne_0.1-3          bitops_1.0-6       
##   [4] webshot_0.5.1       httr_1.4.0          sctransform_0.2.0  
##   [7] tools_3.5.3         R6_2.4.0            irlba_2.3.3        
##  [10] KernSmooth_2.23-15  lazyeval_0.2.2      colorspace_1.4-1   
##  [13] npsurv_0.4-0        withr_2.1.2         tidyselect_0.2.5   
##  [16] compiler_3.5.3      rvest_0.3.4         xml2_1.2.0         
##  [19] labeling_0.3        caTools_1.17.1.2    scales_1.0.0       
##  [22] lmtest_0.9-37       readr_1.3.1         ggridges_0.5.1     
##  [25] pbapply_1.4-0       stringr_1.4.0       digest_0.6.19      
##  [28] rmarkdown_1.12      R.utils_2.8.0       base64enc_0.1-3    
##  [31] pkgconfig_2.0.2     htmltools_0.3.6     bibtex_0.4.2       
##  [34] highr_0.8           htmlwidgets_1.3     rlang_0.3.4        
##  [37] rstudioapi_0.10     shiny_1.3.2         zoo_1.8-5          
##  [40] jsonlite_1.6        crosstalk_1.0.0     ica_1.0-2          
##  [43] gtools_3.8.1        R.oo_1.22.0         Matrix_1.2-17      
##  [46] Rcpp_1.0.1          munsell_0.5.0       ape_5.3            
##  [49] reticulate_1.12     R.methodsS3_1.7.1   stringi_1.4.3      
##  [52] yaml_2.2.0          gbRd_0.4-11         MASS_7.3-51.4      
##  [55] gplots_3.0.1.1      Rtsne_0.15          plyr_1.8.4         
##  [58] grid_3.5.3          promises_1.0.1      parallel_3.5.3     
##  [61] gdata_2.18.0        listenv_0.7.0       ggrepel_0.8.1      
##  [64] crayon_1.3.4        lattice_0.20-38     cowplot_0.9.4      
##  [67] splines_3.5.3       hms_0.4.2           SDMTools_1.1-221.1 
##  [70] pillar_1.4.0        igraph_1.2.4.1      future.apply_1.2.0 
##  [73] reshape2_1.4.3      codetools_0.2-16    glue_1.3.1         
##  [76] evaluate_0.13       lsei_1.2-0          metap_1.1          
##  [79] data.table_1.12.2   httpuv_1.5.1        png_0.1-7          
##  [82] Rdpack_0.11-0       gtable_0.3.0        RANN_2.6.1         
##  [85] purrr_0.3.2         tidyr_0.8.3         future_1.13.0      
##  [88] assertthat_0.2.1    xfun_0.7            mime_0.6           
##  [91] rsvd_1.0.0          xtable_1.8-4        later_0.8.0        
##  [94] survival_2.44-1.1   viridisLite_0.3.0   tibble_2.1.1       
##  [97] cluster_2.0.9       globals_0.12.4      fitdistrplus_1.0-14
## [100] ROCR_1.0-7
LS0tCnRpdGxlOiAiRXhwZXJpbWVudF9QcmVwcm9jZXNzaW5nIgphdXRob3I6ICJEZWxwaGluZSBQb3RpZXIgLyBNYXRoaXMgTm96YWlzIC8gU2FyYW4gUGFua2FldyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDE4MDBweDsKICBtYXJnaW4tbGVmdDogYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87Cn0KPC9zdHlsZT4KCmBgYHtyIGdsb2JhbC1vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSxmaWcuYWxpZ24gPSAnY2VudGVyJykKYGBgCgoKI3RvIGRvIGJlZm9yZSBwdWJsaXNoCmBgYHtyfQojY2hhbmdlIGFsbCBwYXRoIHRvIGRhdGEgc2hvd2luZyBteSBlbnZpcm9ubWVudCAoTkFTLi4uKSBtZXR0cmUgbGllbiDDoCBwYXJ0aXIgZGUgV29ya3NwYWNlIG91IGlsIGRvd2xvYWRlcm9udCBsZXMgZmljaGllciBzb3VyY2UgKGZhc3RxIGV0IG9iamV0IFIpCiNham91dGVyIHVuIHRlc3QgcG91ciBldHJlIHN1ciBxdWUgeSdhaSBzdWJzZXQgMSBldCAyIGV0IHBhcyBxdWUgdW4gZGVzIGRldXggCgojZG8gd2Ugd2FudCB0byBzaG93IHRoZSBjb2RlIGluIHJtZCA/IAoKIyBHTyBtaXNlIGVuIGxpZ25lIGRlcyBmaWNoaWVyIGJydXQKCiN0ZXN0IGZpbmFsIHNhbnMgYXVjdW4gb2JqZXQsIGF2ZWMgbGUgcHJlbWllciBvYmogZXQgYXZlYyBsZSBkZXV4aWVtZQoKI2NoYW5nZSBvdXRwdXQgcGF0aApgYGAKCgoKYGBge3IgZW52X2xvYWRpbmcsIGluY2x1ZGU9RkFMU0V9CiMgTG9hZCBwYWNrYWdlcywgZGF0YSBhbmQgZnVuY3Rpb25zCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKI1BhdGggdG8gdGhlIGFuYWx5c2lzIGZvbGRlcgpXT1JLU1BBQ0UgPC0gIi9ob21lL25vemFpc20vV29ya3NwYWNlLzAxX1RoZXNlLzAxX1Byb2plY3QvTXljX1B0ZW5fUGFwZXIvTXljX3JlcG8vIgojIFBhdGggdG8gdGhlIGZvbGRlciBjb250YWluaW5nIHNjcmlwdHMgdXNlZCBpbiB0aGUgYW5hbHlzaXMKQ1dEIDwtICIvaG9tZS9ub3phaXNtL1dvcmtzcGFjZS9GdW5jdGlvbl9kZWxwaGluZS8iIAojIExvYWQgdGhlIFIgc2NyaXB0cyBjb250YWluaW5nIHRoZSBmdW5jdGlvbnMgdXNlZCBpbiB0aGUgYW5hbHlzaXMKc291cmNlKHBhc3RlKENXRCwgIldvcmtmbG93X2Z1bmN0aW9uc19TMy5SIiwgc2VwPSIvIikpCiMgIFBhdGggdG8gdGhlIGZvbGRlciB0aGF0IHdpbGwgY29udGFpbiBvdXRwdXQgb2JqZWN0cwojT1VUUFVUX1BBVEggPC0gKHBhc3RlMChXT1JLU1BBQ0UsIjAyX1NldXJhdF9hbmFseXNpcy8wMl9PdXRwdXQvIikpCk9VVFBVVF9QQVRIIDwtICgiL2hvbWUvbm96YWlzbS9Xb3Jrc3BhY2UvMDFfVGhlc2UvMDFfUHJvamVjdC9NeWNfUHRlbl9QYXBlci9PdXRwdXRfcmVwby8iKQojIFNldCB0aGUgcmFuZG9tIG51bWJlciBzZWVkCnNldC5zZWVkKDEyMzQpCiMgUmVzb2x1dGlvbiBwYXJhbWV0ZXIgZm9yIFNldXJhdCBjbHVzdGVyaW5nClJFU09MVVRJT04gPC0gMQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLHJlc3VsdHM9J2FzaXMnfQpTQU1QTEUxIDwtICIxODEwMzEiClNBTVBMRTIgPC0gIjE5MDIxMSIKCmlmKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldDJfdG9tZXJnZV8iLCBTQU1QTEUyLCAiLlJvYmoiKSkpewpwcmludCgiWW91IGFyZSBzdGFydGluZyB0aGUgYW5hbHlzaXMgZnJvbSBjb3VudCBtYXRyaXggb2J0YWluIHdpdGggQ2VsbFJhbmdlciBhbmQgQ2l0ZS1zZXEtY291bnQiKQpwYXJ0MSA8LSBUUlVFICNleHBlcmltZW50IG9uZSBieSBvbmUKcGFydDIgPC0gVFJVRSAjbWVyZ2luZyAyIG9iamVjdAp9ZWxzZSBpZiggZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldCIsIi5Sb2JqIikpKXsKcHJpbnQoIllvdSBhbHJlYWR5IGhhdmUgdGhlIGZpbmFsIG9iamVjdCBvZiBwcmVwcm9jZXNzaW5nLCB5b3UgY2FuIG5vdyBsYXVjaCB0aGUgRXhwZXJpbWVudF9hbmFseXNpcyBzY3JpcHQiKQpwYXJ0MSA8LSBGQUxTRQpwYXJ0MiA8LSBGQUxTRQp9ZWxzZXsgCnByaW50ICgiWW91IGFyZSBzdGFydGluZyBhbmFseXNpcyBmcm9tIG91ciB0d28gcmVwbGljYXRlIFJvYmogaW4gb3JkZXIgdG8gZG8gdGhlIGludGVncmF0aW9uIikKcGFydDEgPC0gRkFMU0UKcGFydDIgPC0gVFJVRQp9CgpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMgTG9hZGluZyB0aGUgZmlyc3QgZXhwZXJpbWVudApgYGAKCgpgYGB7ciBwYXRoMV9sb2FkaW5nLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKX0KIyBMb2FkIHBhdGggZm9yIGZpbGVzClBBVEhfTU9VU0VfREFUQTEgPC0gIi9tbnQvTkFTNi9CTmxhYi9TYXJhbi9SZXJ1bl9DZWxsUmFuZ2VyL01ZQ19QVEVOXzAxX21tMTAvb3V0cy9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeC8iClBST0pFQ1RfTkFNRTEgPC0gcGFzdGUoIjEwWF8iLCBTQU1QTEUxLCBzZXAgPSAiIikKUEFUSF9IVE9fREFUQTEgPC0gIi9tbnQvTkFTNS9CTmxhYi9kZWxwaGluZS9iYXJlY29kZWRfc2NSTkFzZXEvTVlDX1BURU4vQ0lURS1zZXEtY291bnRfMTgxMDMxX1Jlc3VsdF9oZDIvdW1pX2NvdW50LyIKYGBgCgpgYGB7ciBTYW1wbGUxX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgQ3JlYXRlIFNldXJhdCBvYmplY3QgYW5kIGFwcGx5IGZpbHRlcmluZyAgIAojIFJlYWQgMTBYIGRhdGEKbW91c2VfZGF0YTEgPC0gUmVhZDEwWChkYXRhLmRpciA9IFBBVEhfTU9VU0VfREFUQTEpCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCBhbmQgZmlyc3QgZmlsdGVyCk5vdF9wcm9jZXNzZWRfU2V1cmF0X20xIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBtb3VzZV9kYXRhMSwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwLCBwcm9qZWN0ID0gIjE4MTAzMSIpCmBgYAoKYGBge3IgSFRPMV9sb2FkaW5nLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojIExvYWQgaW4gdGhlIFVNSSBtYXRyaXgKdW1pX3NwYXJzZTEgPC0gR2V0QXNzYXlEYXRhKG9iamVjdCA9IE5vdF9wcm9jZXNzZWRfU2V1cmF0X20xLCBzbG90ID0gImNvdW50cyIpCgojIExvYWQgaW4gdGhlIEhUTyBjb3VudCBtYXRyaXgKcmF3Lmh0bzEgPC0gUmVhZDEwWChQQVRIX0hUT19EQVRBMSwgZ2VuZS5jb2x1bW4gPSAxKQpodG8xIDwtIHJhdy5odG8xW2MoMTo4KSxdCgpyb3duYW1lcyhodG8xKSA8LSBjKCJTcGxlZW4tTVAiLCJTcGxlZW4tTSIsIlNwbGVlbi1jdHJsIiwiU3BsZWVuLVAiLCJUaHltdXMtTVAiLCJUaHltdXMtTSIsIlRoeW11cy1jdHJsIiwiVGh5bXVzLVAiKQoKIyBTZWxlY3QgY2VsbCBiYXJjb2RlcyBkZXRlY3RlZCBieSBib3RoIFJOQSBhbmQgSFRPCiMgSW4gdGhlIGV4YW1wbGUgZGF0YXNldHMgd2UgaGF2ZSBhbHJlYWR5IGZpbHRlcmVkIHRoZSBjZWxscyBmb3IgeW91LCBidXQgcGVyZm9ybSB0aGlzIHN0ZXAgZm9yIGNsYXJpdHkuCmpvaW50X2JjczEgPC0gaW50ZXJzZWN0KGNvbG5hbWVzKHVtaV9zcGFyc2UxKSxjb2xuYW1lcyhodG8xKSkKCiMgU3Vic2V0IFJOQSBhbmQgSFRPIGNvdW50cyBieSBqb2ludCBjZWxsIGJhcmNvZGVzdW1pX3NwYXJzZSA8LSBwYm1jX3VtaV9zcGFyc2VbLGpvaW50X2Jjc10KaHRvMSA8LSBhcy5tYXRyaXgoaHRvMVssam9pbnRfYmNzMV0pCgojIENvbmZpcm0gdGhhdCB0aGUgSFRPIGhhdmUgdGhlIGNvcnJlY3QgbmFtZXMKcHJpbnQgKHJvd25hbWVzKGh0bzEpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9Ckxvb2tpbmcgdG8gSFRPIGRpc3RyaWJ1dGlvbiBhY2Nyb3NzIHNhbXBsZSA6CmBgYAoKYGBge3IgSFRPIGRpc3RyaWJ1dGlvbixldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiNIVE8gZGlzdHJpYnV0aW9uCnBhcihtZnJvdz1jKDEsMSkpCnBhcihsYXM9MikKcGFyKG1hcj1jKDUsMTUsMywzKSkKYmFycGxvdChyb3dTdW1zKGh0bzEpLCBtYWluID0gInNlcXVlbmNlZCBIVE8gZGlzdHJpYnV0aW9uIiwgaG9yaXo9VFJVRSkKcm93U3VtcyhodG8xKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojIyMgU2V0dXAgc2V1cmF0IG9iamVjdCBhbmQgYWRkIGluIHRoZSBodG8gZGF0YQojIFNldHVwIFNldXJhdCBvYmplY3QKaGFzaHRhZzEgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IHVtaV9zcGFyc2UxWyxqb2ludF9iY3MxXSwgYXNzYXkgPSAiUk5BIiwgcHJvamVjdCA9ICIxODEwMzEiKQoKIyBOb3JtYWxpemUgUk5BIGRhdGEgd2l0aCBsb2cgbm9ybWFsaXphdGlvbgpoYXNodGFnMSA8LSBOb3JtYWxpemVEYXRhKGhhc2h0YWcxLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKIyBGaW5kIGFuZCBzY2FsZSB2YXJpYWJsZSBnZW5lcwpoYXNodGFnMSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhoYXNodGFnMSwgcGFydDEucGxvdCA9IEYsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCwgZGlzcGxheS5wcm9ncmVzcyA9IEZBTFNFKQpoYXNodGFnMSA8LSBTY2FsZURhdGEoaGFzaHRhZzEsZ2VuZXMudXNlID0gaGFzaHRhZzFAdmFyLmZlYXR1cmVzLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyMjIEFkZGluZyBIVE8gZGF0YSBhcyBhbiBpbmRlcGVuZGVudCBhc3NheQoKIyBBZGQgSFRPIGRhdGEgYXMgYSBuZXcgYXNzYXkgaW5kZXBlbmRlbnQgZnJvbSBSTkEKaGFzaHRhZzFbWyJIVE8iXV0gPC0gQ3JlYXRlQXNzYXlPYmplY3QoY291bnRzID0gaHRvMSkKaGFzaHRhZzEgPC0gU2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIsc2xvdCA9ICJjb3VudHMiLG5ldy5kYXRhID0gaHRvMSkKIyBOb3JtYWxpemUgSFRPIGRhdGEsIGhlcmUgd2UgdXNlIGNlbnRlcmVkIGxvZy1yYXRpbyAoQ0xSKSB0cmFuc2Zvcm1hdGlvbgpoYXNodGFnMSA8LSBOb3JtYWxpemVEYXRhKGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkNMUiIsZGlzcGxheS5wcm9ncmVzcyA9IEZBTFNFKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMgRGVtdWx0aXBsZXhpbmcgSFRPCmBgYAoKCmBgYHtyIERlbXVsdGlwbGV4aW5nLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojRGVtdWx0aXBsZXggY2VsbHMgYmFzZWQgb24gSFRPIGVucmljaG1lbnQKI1J1biBIVE9kZW11eCBqdXN0IHRvIGdldCB0aGUgSFRPbWF4X0lEIGZpZWQKaGFzaHRhZzEgPC0gSFRPRGVtdXgoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIHBvc2l0aXZlLnF1YW50aWxlID0gMC45OSwgdmVyYm9zZSA9IEZBTFNFKQojSGVyZSB3ZSB1c2UgdGhlIFNldXJhdCBmdW5jdGlvbiBNVUxUSXNlcURlbXV4KCkgdG8gYXNzaWduIHNpbmdsZSBjZWxscyBiYWNrIHRvIHRoZWlyIHNhbXBsZSBvcmlnaW5zLgpoYXNodGFnMSA8LSBNVUxUSXNlcURlbXV4KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLGF1dG9UaHJlc2ggPSBUUlVFLCBtYXhpdGVyID0gMTAscXJhbmdlID0gc2VxKGZyb20gPSAwLjEsIHRvID0gMC45LCBieSA9IDAuMDUpLCB2ZXJib3NlID0gVFJVRSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjRGVtdWx0aXBsZXhpbmcgcmVzdWx0cyB7LnRhYnNldH0KYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjI0NlbGxzIGNsYXNzaWZpY2F0aW9uCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpwcmludCAodGFibGUoaGFzaHRhZzFAbWV0YS5kYXRhJE1VTFRJX0lEKSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgVmlvbGlucGxvdCAoZmVhdHVyZXMpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KVmxuUGxvdChoYXNodGFnMSxmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgVmlvbGlucGxvdCAoSFRPIGNvdW50cykKYGBgCgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcxLGZlYXR1cmVzID0gYygibkNvdW50X0hUTyIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyB0U05FcyBiYXNlZCBvbiBIVE8KYGBgCgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQojIENhbGN1bGF0ZSBhIGRpc3RhbmNlIG1hdHJpeCB1c2luZyBIVE8KaHRvLmRpc3QubXR4IDwtIGFzLm1hdHJpeChkaXN0KHQoR2V0QXNzYXlEYXRhKG9iamVjdCA9IGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iKSkpKQoKIyBDYWxjdWxhdGUgdFNORSBlbWJlZGRpbmdzIHdpdGggYSBkaXN0YW5jZSBtYXRyaXgKaGFzaHRhZzEgPC0gUnVuVFNORShoYXNodGFnMSwgZGlzdGFuY2UubWF0cml4ID0gaHRvLmRpc3QubXR4LCBwZXJwbGV4aXR5ID0gMTAwKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGVjaG89RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CkRpbVBsb3QoaGFzaHRhZzEsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIixyZWR1Y3Rpb24gPSAidHNuZSIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgSFRPIG1hcmdpbgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDcsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpUc25lPC1kYXRhLmZyYW1lKAogIHRTTkVfMSA9IGhhc2h0YWcxQHJlZHVjdGlvbnMkdHNuZUBjZWxsLmVtYmVkZGluZ3NbLDFdLAogIHRTTkVfMj0gaGFzaHRhZzFAcmVkdWN0aW9ucyR0c25lQGNlbGwuZW1iZWRkaW5nc1ssMl0sCiAgZ2VuZT0gaGFzaHRhZzFAbWV0YS5kYXRhJEhUT19tYXJnaW4KKQoKSFRPPSBoYXNodGFnMUBtZXRhLmRhdGEkTVVMVElfSUQKTWF4PW1heChoYXNodGFnMUBtZXRhLmRhdGEkSFRPX21hcmdpbikKTWluPW1pbihoYXNodGFnMUBtZXRhLmRhdGEkSFRPX21hcmdpbikKZ2dwbG90KFRzbmUsYWVzKHg9dFNORV8xLHk9dFNORV8yKSkrZ2VvbV9wb2ludChhZXMoY29sb3I9Z2VuZSxzaGFwZT1IVE8pKSsKICAgICAgICAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdyA9ICJibHVlIixtaWQ9Im9yYW5nZSIsaGlnaD0icmVkIixuYW1lPSJIVE8gbWFyZ2luIixtaWRwb2ludD0oTWF4K01pbikvMikrc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUpKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIFJpZGdlIHBsb3RzCgoqKlZpc3VhbGl6ZSBlbnJpY2htZW50IGZvciBzZWxlY3RlZCBIVE9zIHdpdGggcmlkZ2UgcGxvdHMqKgpgYGAKCgpgYGB7ciwgZmlnLmhlaWdodCA9IDQsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpSaWRnZVBsb3QoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVsxOjJdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpClJpZGdlUGxvdChoYXNodGFnMSwgYXNzYXkgPSAiSFRPIiwgZmVhdHVyZXMgPSByb3duYW1lcyhHZXRBc3NheURhdGEoaGFzaHRhZzEsYXNzYXkgPSAiSFRPIikpWzM6NF0sbmNvbCA9IDIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKUmlkZ2VQbG90KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbNTo2XSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpSaWRnZVBsb3QoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVs3OjhdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KIyMgU2FtcGxlIEluZm9ybWF0aW9uCgpUaGUgYW5hbHlzaXMgd2lsbCBiZSBydW4gb24gdGhlIHNhbXBsZSAxICgxODEwMzEpLgoKRHVyaW5nIHRoZSBzYW1wbGUgbG9hZGluZywgd2UgZmlsdGVyIGNlbGxzIHRoYXQgZG8gbm90IHBhc3MgdGhlIGZvbGxvd2luZyBmaWx0ZXJzLiAgIApIZXJlIGFyZSB0aGUgZGVzY3JpcHRpb24gb2YgdGhvc2UgcGFyYW1ldGVycyBpbiB0aGUgU2V1cmF0ICpDcmVhdGVTZXVyYXRPYmplY3QqIGZ1bmN0aW9uOgogIAoqIG1pbi5nZW5lczogSW5jbHVkZSBjZWxscyB3aGVyZSBhdCBsZWFzdCAyMDAgZ2VuZXMgYXJlIGRldGVjdGVkCiogbWluLmNlbGxzOiBJbmNsdWRlIGdlbmVzIHdpdGggZGV0ZWN0ZWQgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCAzIGNlbGxzCgpBZnRlciB0aG9zZSBmaWx0ZXJzLCB0aGUgcmVtYWluaW5nIGNlbGwgbnVtYmVyIGlzICoqYHIgbGVuZ3RoKGNvbG5hbWVzKGhhc2h0YWcxQGFzc2F5cyRSTkFAZGF0YSkpKiouCmBgYAoKYGBge3IgZG91YmxldF9uZWdhdGl2ZV9yZW1vdmFsLCByZXN1bHRzPSdhc2lzJyxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiNhZGQgRXhwMSBjZWxsIGlkZW50aXR5CkhUT19jcjEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tY3RybCIgKSkKSFRPX2N0MSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1jdHJsIiApKQpIVE9fbXIxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU0iICkpCkhUT19tdDEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTSIgKSkKSFRPX3ByMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1QIiApKQpIVE9fcHQxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLVAiICkpCkhUT19wbXIxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiApKQpIVE9fcG10MSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NUCIgKSkKSFRPX2QxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiRG91YmxldCIgKSkKSFRPX24xIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiTmVnYXRpdmUiICkpCgpIVE9fdGh5bXVzMSA9IGMoSFRPX2N0MSxIVE9fbXQxLEhUT19wdDEsSFRPX3BtdDEpCkhUT19zcGxlZW4xID0gYyhIVE9fY3IxLEhUT19tcjEsSFRPX3ByMSxIVE9fcG1yMSkKSFRPX2lkZW50aWZpZWQxID0gYyhIVE9fdGh5bXVzMSwgSFRPX3NwbGVlbjEpCgoKIyBDcmVhdGUgYSBTZXVyYXQgb2JqZWN0IHdpdGhvdXQgZG91YmxldCBhbmQgdW5hc3NpZ25lZCBjZWxscyAocmVtb3ZlICJuZWdhdGl2ZSIsICJkb3VibGV0IiAmICJub3RoaW5nIikpCmNsZWFuLnN1YnNldDEgPC0gc3Vic2V0KHggPSBoYXNodGFnMSwgY2VsbHMgPSBIVE9faWRlbnRpZmllZDEpClZsblBsb3QoY2xlYW4uc3Vic2V0MSxmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIikscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CkFmdGVyIHJlbW92aW5nIGRvdWJsZXRzIGFuZCBuZWdhdGl2ZSBjZWxscywgdGhlIHJlbWFpbmluZyBjZWxsIG51bWJlciBpcyAqKmByIGxlbmd0aChjb2xuYW1lcyhjbGVhbi5zdWJzZXQxQGFzc2F5cyRSTkFAZGF0YSkpKiouCmBgYAoKCmBgYHtyIHByb2Nlc3NpbmdfMSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBPQkpFQ1QgT05FIFNBVkUKCmlmKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldDFfdG9tZXJnZV8iLCBTQU1QTEUxLCAiLlJvYmoiKSkpewogICMxLSBRQyAoZmFpdCDDoCBwYXJ0aXIgZGUgbGEgc291cyBzw6lsZWN0aW9uKQogIFNldXJhdDEgPC0gUUNfZnVuY3Rpb25fbWl0b190aHJlc2hvbGQoU2V1cmF0ID0gY2xlYW4uc3Vic2V0MSwgbWl0b190aHJlc2hvbGQgPSAwLjEsIGRvX3Bsb3QgPSBGQUxTRSkKICAKICAjMi0gRmluZCB2YXJpYWJsZSBnZW5lcwogIFNldXJhdDEgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIGRvLnBsb3Q9VFJVRSkKICAKICBTZXVyYXQxIDwtIFNjYWxlRGF0YShTZXVyYXQxLCAKICAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iUk5BIiwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICNkby5zY2FsZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQogIAogIFNldXJhdDEgPC0gUnVuUENBKG9iamVjdCA9IFNldXJhdDEsCiAgICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiUk5BIiwKICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsICNpZiBUUlVFIHByaW50IHRoZSB0b3AgZ2VuZXMgZm9yIGVhY2ggUEMKICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9ICBWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IFNldXJhdDEpLCAKICAgICAgICAgICAgICAgICAgICBzZWVkLnVzZSA9IDEyMzQsCiAgICAgICAgICAgICAgICAgICAgbnBjcyA9IDUwKSAjIHN1ciBsZXMgNTAgcHJlbWllcmVzIGNvbXBvc2FudGVzCiAgCiAgRWxib3dQbG90KFNldXJhdDEsIG5kaW1zID0gNTAsIHJlZHVjdGlvbiA9ICJwY2EiKQogIAogIAogIFNldXJhdDEgPC0gUHJvamVjdERpbShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCiAgCiAgU2V1cmF0MSA8LSBSdW5UU05FKG9iamVjdCA9IFNldXJhdDEsCiAgICAgICAgICAgICAgICAgICAgIGRvLmZhc3QgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgc2VlZC51c2UgPSAxMjM0LAogICAgICAgICAgICAgICAgICAgICBkaW1zID0gMToyMCwgIyBVc2VzIDIwIGZpcnN0IFBDcwogICAgICAgICAgICAgICAgICAgICBwZXJwbGV4aXR5ID0gNDApCiAgCiAgU2V1cmF0MSA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IFNldXJhdDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zID0gMToyMCAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZS5yZWNhbGMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uID0gInBjYSIpCiAgCiAgU2V1cmF0MSA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gU2V1cmF0MSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbiA9IFJFU09MVVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbS5zZWVkID0gMTIzNCkKICAKICBTZXVyYXQxIDwtIFJ1blVNQVAob2JqZWN0ID0gU2V1cmF0MSwgcmVkdWN0aW9uID0gInBjYSIsIHNlZWQudXNlID0gMTIzNCwgZGltcyA9IDE6MjApCiAgCiAgc2F2ZShTZXVyYXQxLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldDFfdG9tZXJnZV8iLCBTQU1QTEUxLCAiLlJvYmoiKSkKfWVsc2V7CiAgbG9hZChwYXN0ZTAoT1VUUFVUX1BBVEgsICJTZXVyYXRfY2xlYW4tc3Vic2V0MV90b21lcmdlXyIsIFNBTVBMRTEsICIuUm9iaiIpKQp9CmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgTWl0b2Nob25kcmlhbCBwZXJjZW50YWdlIHZlcnN1cyBuRmVhdHVyZXMKYGBgCgpgYGB7ciBtaXRvX3ZzX25mZWF0dXJlcyxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CmRmPC1kYXRhLmZyYW1lKG11bHRpLmlkPVNldXJhdDFAbWlzYyRvbGRfbWV0YV9kYXRhJE1VTFRJX0lELHBlcmNlbnQubWl0bz1TZXVyYXQxQG1pc2Mkb2xkX21ldGFfZGF0YSRwZXJjZW50Lm1pdG8sbkZlYXR1cmVfUk5BPVNldXJhdDFAbWlzYyRvbGRfbWV0YV9kYXRhJG5GZWF0dXJlX1JOQSkKZ2dwbG90bHkoZ2dwbG90KGRmLGFlcyh4PW5GZWF0dXJlX1JOQSx5PXBlcmNlbnQubWl0byxjb2xvcj1tdWx0aS5pZCkpK2dlb21fcG9pbnQoKSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBVTUFQCmBgYAoKYGBge3IgVU1BUF9IVE9fc2V1cmF0XzEsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpnZ3Bsb3RseShEaW1QbG90KFNldXJhdDEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiLCBkby5sYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAxKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMgTG9hZGluZyB0aGUgc2Vjb25kIGV4cGVyaW1lbnQKYGBgCgoKYGBge3IgcGF0aDJfbG9hZGluZywgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBMb2FkIHBhdGggZm9yIGZpbGVzClBBVEhfTU9VU0VfREFUQTIgPC0gIi9tbnQvTkFTNi9CTmxhYi9TYXJhbi9SZXJ1bl9DZWxsUmFuZ2VyL01ZQ19QVEVOXzAyX21tMTAvb3V0cy9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeC8iClBST0pFQ1RfTkFNRTIgPC0gcGFzdGUoIjEwWF8iLCBTQU1QTEUyLCBzZXAgPSAiIikKUEFUSF9IVE9fREFUQTIgPC0gIi9tbnQvTkFTNi9CTmxhYi9tYXRoaXMvc2NSTkFzZXEvRE1BVGgzL0NJVEUtc2VxLWNvdW50MTQxXzE5MDIxMV9SZXN1bHRfaGFzaHRhZ19oZDIvdW1pX2NvdW50LyIKUEFUSF9BRFRfREFUQTIgPC0gIi9tbnQvTkFTNS9CTmxhYi9kZWxwaGluZS9iYXJlY29kZWRfc2NSTkFzZXEvTVlDX1BURU4yL0NJVEUtc2VxLWNvdW50MTQxXzE5MDIxMV9BRFQtUmVzdWx0X2hkMi91bWlfY291bnQiCmBgYAoKYGBge3IgU2FtcGxlX2xvYWRpbmdfMiwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBDcmVhdGUgU2V1cmF0IG9iamVjdCBhbmQgYXBwbHkgZmlsdGVyaW5nICAgCiMgUmVhZCAxMFggZGF0YQptb3VzZV9kYXRhMiA8LSBSZWFkMTBYKGRhdGEuZGlyID0gUEFUSF9NT1VTRV9EQVRBMikKCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCBhbmQgZmlyc3QgZmlsdGVyCk5vdF9wcm9jZXNzZWRfU2V1cmF0X20yIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBtb3VzZV9kYXRhMiwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwLCBwcm9qZWN0ID0gIjE5MDIxMSIpCmBgYAoKYGBge3IgLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojIExvYWQgaW4gdGhlIFVNSSBtYXRyaXgKdW1pX3NwYXJzZTIgPC0gR2V0QXNzYXlEYXRhKG9iamVjdCA9IE5vdF9wcm9jZXNzZWRfU2V1cmF0X20yLCBzbG90ID0gImNvdW50cyIpCgojIExvYWQgaW4gdGhlIEhUTyBjb3VudCBtYXRyaXgKcmF3Lmh0bzIgPC0gUmVhZDEwWChQQVRIX0hUT19EQVRBMiwgZ2VuZS5jb2x1bW4gPSAxKQpodG8yIDwtIHJhdy5odG8yW2MoMTo4KSxdCgpyb3duYW1lcyhodG8yKSA8LSBjKCJTcGxlZW4tTVAiLCJTcGxlZW4tTSIsIlNwbGVlbi1jdHJsIiwiU3BsZWVuLVAiLCJUaHltdXMtTVAiLCJUaHltdXMtTSIsIlRoeW11cy1jdHJsIiwiVGh5bXVzLVAiKQoKIyBTZWxlY3QgY2VsbCBiYXJjb2RlcyBkZXRlY3RlZCBieSBib3RoIFJOQSBhbmQgSFRPCmpvaW50X2JjczIgPC0gaW50ZXJzZWN0KGNvbG5hbWVzKHVtaV9zcGFyc2UyKSxjb2xuYW1lcyhodG8yKSkKaHRvMiA8LSBhcy5tYXRyaXgoaHRvMlssam9pbnRfYmNzMl0pCgojIENvbmZpcm0gdGhhdCB0aGUgSFRPIGhhdmUgdGhlIGNvcnJlY3QgbmFtZXMKcHJpbnQgKHJvd25hbWVzKGh0bzIpKQpgYGAKCmBgYHtyLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KcGFyKG1mcm93PWMoMSwxKSkKcGFyKGxhcz0yKQpwYXIobWFyPWMoNSwxNSwzLDMpKQpiYXJwbG90KHJvd1N1bXMoaHRvMiksIG1haW4gPSAic2VxdWVuY2VkIEhUTyBkaXN0cmlidXRpb24iLCBob3Jpej1UUlVFKQoKcm93U3VtcyhodG8yKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojIyMgU2V0dXAgc2V1cmF0IG9iamVjdCBhbmQgYWRkIGluIHRoZSBodG8gZGF0YQojIFNldHVwIFNldXJhdCBvYmplY3QKaGFzaHRhZzIgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IHVtaV9zcGFyc2UyWyxqb2ludF9iY3MyIF0sIGFzc2F5ID0gIlJOQSIsIHByb2plY3QgPSAiMTkwMjExIikKCiMgTm9ybWFsaXplIFJOQSBkYXRhIHdpdGggbG9nIG5vcm1hbGl6YXRpb24KaGFzaHRhZzIgPC0gTm9ybWFsaXplRGF0YShoYXNodGFnMixkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCiMgRmluZCBhbmQgc2NhbGUgdmFyaWFibGUgZ2VuZXMKaGFzaHRhZzIgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoaGFzaHRhZzIsZG8ucGxvdCA9IEYsc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCBkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCmhhc2h0YWcyIDwtIFNjYWxlRGF0YShoYXNodGFnMixnZW5lcy51c2UgPSBoYXNodGFnMkBhc3NheXMkUk5BQHZhci5mZWF0dXJlcyxkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMjIyBBZGRpbmcgSFRPIGRhdGEgYXMgYW4gaW5kZXBlbmRlbnQgYXNzYXkKIyBBZGQgSFRPIGRhdGEgYXMgYSBuZXcgYXNzYXkgaW5kZXBlbmRlbnQgZnJvbSBSTkEKaGFzaHRhZzJbWyJIVE8iXV0gPC0gQ3JlYXRlQXNzYXlPYmplY3QoY291bnRzID0gaHRvMikKaGFzaHRhZzIgPC0gU2V0QXNzYXlEYXRhKGhhc2h0YWcyLGFzc2F5ID0gIkhUTyIsc2xvdCA9ICJjb3VudHMiLG5ldy5kYXRhID0gaHRvMikKIyBOb3JtYWxpemUgSFRPIGRhdGEsIGhlcmUgd2UgdXNlIGNlbnRlcmVkIGxvZy1yYXRpbyAoQ0xSKSB0cmFuc2Zvcm1hdGlvbgpoYXNodGFnMiA8LSBOb3JtYWxpemVEYXRhKGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkNMUiIsZGlzcGxheS5wcm9ncmVzcyA9IEZBTFNFKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojUnVuIEhUT2RlbXV4IGp1c3QgdG8gZ2V0IHRoZSBIVE9fbWF4SUQgZmllbGQKaGFzaHRhZzIgPC0gSFRPRGVtdXgoaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIsIHBvc2l0aXZlLnF1YW50aWxlID0gMC45OSwgdmVyYm9zZSA9IEZBTFNFKQojRGVtdWx0aXBsZXggY2VsbHMgYmFzZWQgb24gSFRPIGVucmljaG1lbnQKaGFzaHRhZzIgPC0gTVVMVElzZXFEZW11eChoYXNodGFnMiwgYXNzYXkgPSAiSFRPIixhdXRvVGhyZXNoID0gVFJVRSwgbWF4aXRlciA9IDEwLHFyYW5nZSA9IHNlcShmcm9tID0gMC4xLCB0byA9IDAuOSwgYnkgPSAwLjA1KSwgdmVyYm9zZSA9IFRSVUUpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojI0RlbXVsdGlwbGV4aW5nIHJlc3VsdHMgey50YWJzZXR9CmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyNDZWxscyBjbGFzc2lmaWNhdGlvbgpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KcHJpbnQgKHRhYmxlKGhhc2h0YWcyQG1ldGEuZGF0YSRNVUxUSV9JRCkpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgVmlvbGlucGxvdCAoZmVhdHVyZXMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcyLGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIikscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBWaW9saW4gcGxvdHMgKEhUTyBjb3VudHMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcyLGZlYXR1cmVzID0gYygibkNvdW50X0hUTyIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyB0U05FcyBiYXNlZCBvbiBIVE8KYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMgQ2FsY3VsYXRlIGEgZGlzdGFuY2UgbWF0cml4IHVzaW5nIEhUTwpodG8uZGlzdC5tdHggPC0gYXMubWF0cml4KGRpc3QodChHZXRBc3NheURhdGEob2JqZWN0ID0gaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIpKSkpCgojIENhbGN1bGF0ZSB0U05FIGVtYmVkZGluZ3Mgd2l0aCBhIGRpc3RhbmNlIG1hdHJpeApoYXNodGFnMiA8LSBSdW5UU05FKGhhc2h0YWcyLCBkaXN0YW5jZS5tYXRyaXggPSBodG8uZGlzdC5tdHgsIHBlcnBsZXhpdHkgPSAxMDApCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpEaW1QbG90KGhhc2h0YWcyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgSFRPIG1hcmdpbgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDcsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpUc25lPC1kYXRhLmZyYW1lKAogIHRTTkVfMSA9IGhhc2h0YWcyQHJlZHVjdGlvbnMkdHNuZUBjZWxsLmVtYmVkZGluZ3NbLDFdLAogIHRTTkVfMj0gaGFzaHRhZzJAcmVkdWN0aW9ucyR0c25lQGNlbGwuZW1iZWRkaW5nc1ssMl0sCiAgZ2VuZT0gaGFzaHRhZzJAbWV0YS5kYXRhJEhUT19tYXJnaW4KKQoKSFRPPSBoYXNodGFnMkBtZXRhLmRhdGEkTVVMVElfSUQKTWF4PW1heChoYXNodGFnMkBtZXRhLmRhdGEkSFRPX21hcmdpbikKTWluPW1pbihoYXNodGFnMkBtZXRhLmRhdGEkSFRPX21hcmdpbikKCmdncGxvdChUc25lLGFlcyh4PXRTTkVfMSx5PXRTTkVfMikpK2dlb21fcG9pbnQoYWVzKGNvbG9yPWdlbmUsc2hhcGU9SFRPKSkrCiAgICAgICAgICAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsbWlkPSJvcmFuZ2UiLGhpZ2g9InJlZCIsbmFtZT0iSFRPIG1hcmdpbiIsbWlkcG9pbnQ9KE1heCtNaW4pLzIpK3NjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1KSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBSaWRnZSBwbG90cwoKKipWaXN1YWxpemUgZW5yaWNobWVudCBmb3Igc2VsZWN0ZWQgSFRPcyB3aXRoIHJpZGdlIHBsb3RzKioKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQgPSA0LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KUmlkZ2VQbG90KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbMToyXSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpSaWRnZVBsb3QoaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVszOjRdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpClJpZGdlUGxvdChoYXNodGFnMiwgYXNzYXkgPSAiSFRPIiwgZmVhdHVyZXMgPSByb3duYW1lcyhHZXRBc3NheURhdGEoaGFzaHRhZzEsYXNzYXkgPSAiSFRPIikpWzU6Nl0sbmNvbCA9IDIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKUmlkZ2VQbG90KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbNzo4XSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CgojIyBTYW1wbGUgSW5mb3JtYXRpb24KClRoZSBhbmFseXNpcyB3aWxsIGJlIHJ1biBvbiB0aGUgc2FtcGxlIDIgKDE5MDIxMSkuCgpEdXJpbmcgdGhlIHNhbXBsZSBsb2FkaW5nLCB3ZSBmaWx0ZXIgY2VsbHMgdGhhdCBkbyBub3QgcGFzcyB0aGUgZm9sbG93aW5nIGZpbHRlcnMuCgpVc2VkIHBhcmFtZXRlcnMgaW4gdGhlIFNldXJhdCAqQ3JlYXRlU2V1cmF0T2JqZWN0KiBmdW5jdGlvbjoKKiBtaW4uZ2VuZXM6IDMgLiBJbmNsdWRlIGNlbGxzIHdoZXJlIGF0IGxlYXN0IDMgZ2VuZXMgYXJlIGRldGVjdGVkCiogbWluLmNlbGxzOiAyMDAgLiBJbmNsdWRlIGdlbmVzIHdpdGggZGV0ZWN0ZWQgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCAyMDAgY2VsbHMKCkFmdGVyIHRob3NlIGZpbHRlcnMsIHRoZSByZW1haW5pbmcgY2VsbCBudW1iZXIgaXMgKipgciBsZW5ndGgoY29sbmFtZXMoaGFzaHRhZzJAYXNzYXlzJFJOQUBkYXRhKSkqKi4KYGBgCgoKYGBge3IgY2VsbF9zZWxlY3RfMiwgcmVzdWx0cz0nYXNpcycsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQojYWRkIEV4cDIgY2VsbCBpZGVudGl0eQpIVE9fY3IyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpCkhUT19jdDIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1jdHJsIiApKQpIVE9fbXIyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tTSIgKSkKSFRPX210MiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiVGh5bXVzLU0iICkpCkhUT19wcjIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1QIiApKQpIVE9fcHQyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtUCIgKSkKSFRPX3BtcjIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1NUCIgKSkKSFRPX3BtdDIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1NUCIgKSkKSFRPX2QyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJEb3VibGV0IiApKQpIVE9fbjIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIk5lZ2F0aXZlIiApKQoKSFRPX3RoeW11czIgPSBjKEhUT19jdDIsSFRPX210MixIVE9fcHQyLEhUT19wbXQyKQpIVE9fc3BsZWVuMiA9IGMoSFRPX2NyMixIVE9fbXIyLEhUT19wcjIsSFRPX3BtcjIpCkhUT19pZGVudGlmaWVkMiA9IGMoSFRPX3RoeW11czIsIEhUT19zcGxlZW4yKQoKIyBDcmVhdGUgYSBTZXVyYXQgb2JqZWN0IHdpdGhvdXQgZG91YmxldCBhbmQgdW5hc3NpZ25lZCBjZWxscyAocmVtb3ZlICJuZWdhdGl2ZSIsICJkb3VibGV0IiAmICJub3RoaW5nIikpCmNsZWFuLnN1YnNldDIgPC0gc3Vic2V0KHggPSBoYXNodGFnMiwgY2VsbHMgPSBIVE9faWRlbnRpZmllZDIpClZsblBsb3QoY2xlYW4uc3Vic2V0MixmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIikscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQpBZnRlciByZW1vdmluZyBkb3VibGV0cyBhbmQgbmVnYXRpdmUgY2VsbHMsIHRoZSByZW1haW5pbmcgY2VsbCBudW1iZXIgaXMgKipgciBsZW5ndGgoY29sbmFtZXMoY2xlYW4uc3Vic2V0MkBhc3NheXMkUk5BQGRhdGEpKSoqLgpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgQWRkaW5nIEFEVApgYGAKCgpgYGB7ciBsb2FkX2FkdCwgIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQojIExvYWQgaW4gdGhlIFVNSSBtYXRyaXgKdW1pIDwtIEdldEFzc2F5RGF0YShvYmplY3QgPSBjbGVhbi5zdWJzZXQyLCBzbG90ID0gImNvdW50cyIpCgojIExvYWQgaW4gdGhlIEFEVCBjb3VudCBtYXRyaXgKcmF3LmFkdCA8LSBSZWFkMTBYKFBBVEhfQURUX0RBVEEyLCBnZW5lLmNvbHVtbiA9IDEpCmFkdCA8LSByYXcuYWR0W2MoMTo2KSxdCgpyb3duYW1lcyhhZHQpIDwtIGMoIkNENCIsIkNENSIsIkNEOCIsIkNEMjUiLCJDRDQ0IiwiQ0Q2OSIpCgojY3JlYXRlIGFuIGVtcHR5IG1hdHJpeCBjb250YWluaW5nIE5BcwpDZWxsLmxpc3QgPC0gY29sbmFtZXMoR2V0QXNzYXlEYXRhKG9iamVjdCA9IGNsZWFuLnN1YnNldDJbWyJSTkEiXV0sIHNsb3QgPSAiZGF0YSIgKSApCkFEVC5saXN0IDwtIGModW5pcXVlKHJvd25hbWVzKGFkdCkpKQptYXQuYWR0IDwtIG1hdHJpeChucm93ID0gbGVuZ3RoKEFEVC5saXN0KSwgbmNvbCA9IGxlbmd0aChDZWxsLmxpc3QpKQpyb3duYW1lcyhtYXQuYWR0KSA9IEFEVC5saXN0CmNvbG5hbWVzKG1hdC5hZHQpID0gQ2VsbC5saXN0CgojIEdldCBjZWxsIGJhcmNvZGVzIGRldGVjdGVkIGJ5IGJvdGggUk5BIGFuZCBBRFQKam9pbnRfYmNzIDwtIGludGVyc2VjdChjb2xuYW1lcyh1bWkpLGNvbG5hbWVzKGFkdCkpCmFkdCA8LSBhcy5tYXRyaXgoYWR0Wyxqb2ludF9iY3NdKQoKIyBGaWxsIHRoZSBlbXB0eSBtYXRyaXggd2l0aCB2YWx1ZXMgd2hlbiBleGlzdGluZwptYXQuYWR0Wyxqb2ludF9iY3NdPC1hZHRbLGpvaW50X2Jjc10KCiMgQWRkIEFEVCBkYXRhIGFzIGEgbmV3IGFzc2F5IGluZGVwZW5kZW50IGZyb20gUk5BCmNsZWFuLnN1YnNldDJbWyJBRFQiXV0gPC0gQ3JlYXRlQXNzYXlPYmplY3QoY291bnRzID0gbWF0LmFkdFssY29sbmFtZXMoY2xlYW4uc3Vic2V0MildKQoKIyBOb3JtYWxpemUgQURUIGRhdGEsIGhlcmUgd2UgdXNlIGNlbnRlcmVkIGxvZy1yYXRpbyAoQ0xSKSB0cmFuc2Zvcm1hdGlvbgpjbGVhbi5zdWJzZXQyIDwtIE5vcm1hbGl6ZURhdGEoY2xlYW4uc3Vic2V0MiwgYXNzYXkgPSAiQURUIiwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiQ0xSIikKCiNTY2FsZQpjbGVhbi5zdWJzZXQyIDwtIFNjYWxlRGF0YShjbGVhbi5zdWJzZXQyLCBhc3NheSA9ICJBRFQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KQURUIGxpc3QgOgpgYGAKCgpgYGB7ciAsIHJlc3VsdHM9J2FzaXMnLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KcHJpbnQgKHJvd25hbWVzKGFkdCkpCmBgYAoKYGBge3IgU2lnbmlmaWNhbnRfUEMsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgVHJhaXRlbWVudCBkZSBsJ29iamV0CmlmKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldDJfdG9tZXJnZV8iLCBTQU1QTEUyLCAiLlJvYmoiKSkpewogICMxLSBRQyAKICBTZXVyYXQyIDwtIFFDX2Z1bmN0aW9uX21pdG9fdGhyZXNob2xkKFNldXJhdCA9IGNsZWFuLnN1YnNldDIsIG1pdG9fdGhyZXNob2xkID0gMC4xLCBkb19wbG90ID0gRkFMU0UpCiAgCiAgIzItIEZpbmQgdmFyaWFibGUgZ2VuZXMKICBTZXVyYXQyIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IFNldXJhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiUk5BIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCwgdmVyYm9zZSA9IEZBTFNFLCBkby5wbG90PVRSVUUpCiAgCiAgU2V1cmF0MiA8LSBTY2FsZURhdGEoU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgYXNzYXk9IlJOQSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAjZG8uc2NhbGUgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgZG8uY2VudGVyID0gVFJVRSkKICAKICBTZXVyYXQyIDwtIFJ1blBDQShvYmplY3QgPSBTZXVyYXQyLAogICAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlJOQSIsCiAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCAjaWYgVFJVRSBwcmludCB0aGUgdG9wIGdlbmVzIGZvciBlYWNoIFBDCiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAgVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBTZXVyYXQyKSwgCiAgICAgICAgICAgICAgICAgICAgc2VlZC51c2UgPSAxMjM0LAogICAgICAgICAgICAgICAgICAgIG5wY3MgPSA1MCkgCiAgCiAgRWxib3dQbG90KFNldXJhdDIsIG5kaW1zID0gNDAsIHJlZHVjdGlvbiA9ICJwY2EiKQogIAogIFNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFNldXJhdDIsCiAgICAgICAgICAgICAgICAgICAgICAgbmZlYXR1cmVzLnByaW50ID0gMjAsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCgogIFNldXJhdDIgPC0gUnVuVFNORShvYmplY3QgPSBTZXVyYXQyLAogICAgICAgICAgICAgICAgICAgICBkby5mYXN0ID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMTIzNCwKICAgICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MjAsIAogICAgICAgICAgICAgICAgICAgICBwZXJwbGV4aXR5ID0gNDApCiAgCiAgU2V1cmF0MiA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IFNldXJhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zID0gMToyMCAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZS5yZWNhbGMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uID0gInBjYSIpCiAgCiAgU2V1cmF0MiA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbiA9IFJFU09MVVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbS5zZWVkID0gMTIzNCkKICAKICBTZXVyYXQyIDwtIFJ1blVNQVAob2JqZWN0ID0gU2V1cmF0MiwgcmVkdWN0aW9uID0gInBjYSIsIHNlZWQudXNlID0gMTIzNCwgZGltcyA9IDE6MjApCiAgCiAgc2F2ZShTZXVyYXQyLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldDJfdG9tZXJnZV8iLCBTQU1QTEUyLCAiLlJvYmoiKSkKfWVsc2V7CiAgbG9hZChwYXN0ZTAoT1VUUFVUX1BBVEgsICJTZXVyYXRfY2xlYW4tc3Vic2V0Ml90b21lcmdlXyIsIFNBTVBMRTIsICIuUm9iaiIpKQp9CmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBNaXRvY2hvbmRyaWFsIHBlcmNlbnRhZ2UgdmVyc3VzIG5GZWF0dXJlcwpgYGAKCmBgYHtyIG1pdG9fdnNfbmZlYXR1cmVzMixldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CmRmPC1kYXRhLmZyYW1lKG11bHRpLmlkPVNldXJhdDJAbWlzYyRvbGRfbWV0YV9kYXRhJE1VTFRJX0lELHBlcmNlbnQubWl0bz1TZXVyYXQyQG1pc2Mkb2xkX21ldGFfZGF0YSRwZXJjZW50Lm1pdG8sbkZlYXR1cmVfUk5BPVNldXJhdDJAbWlzYyRvbGRfbWV0YV9kYXRhJG5GZWF0dXJlX1JOQSkKZ2dwbG90bHkoZ2dwbG90KGRmLGFlcyh4PW5GZWF0dXJlX1JOQSx5PXBlcmNlbnQubWl0byxjb2xvcj1tdWx0aS5pZCkpK2dlb21fcG9pbnQoKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFVNQVA6CmBgYAoKYGBge3IgVU1BUF9IVE9fc2V1cmF0XzIsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpnZ3Bsb3RseShEaW1QbG90KFNldXJhdDIsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiLCBkby5sYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAxKSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojTWVyZ2luZyBvdXIgdHdvIGV4cGVyaW1lbnRzCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBMb2FkIHNlcGFyYXRlIFIgb2JqZWN0CllvdSBjYW4gbG9hZCBvYmplY3RzIGRvbmUgd2l0aCB0aGUgY29kZSBhYm92ZS4KT3Igb3VyIG9iamVjdCA/PyAobGluayApCmBgYAoKYGBge3IgU2FtcGxlc19sb2FkaW5nLGV2YWw9KHBhcnQyID09IFRSVUUgKSAsaW5jbHVkZT1GQUxTRX0KI2xvYWQgYWxsIHNldXJhdCBvYmplY3RzIGJ1aWx0IHByZXZpb3VzbHkKbG9hZChwYXN0ZTAoT1VUUFVUX1BBVEgsICJTZXVyYXRfY2xlYW4tc3Vic2V0MV90b21lcmdlXyIsIFNBTVBMRTEsICIuUm9iaiIpKQpsb2FkKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdF9jbGVhbi1zdWJzZXQyX3RvbWVyZ2VfIiwgU0FNUExFMiwgIi5Sb2JqIikpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBJbnRlZ3JhdGluZyB0aGUgMiBzZXVyYXQgb2JqZWN0cyB3aXRoIHNldXJhdCBpbnRlZ3JhdGlvbiAoY2NhKQpgYGAKCmBgYHtyLCBDQ0EsIGV2YWw9KHBhcnQyID09IFRSVUUgKSxpbmNsdWRlPUZBTFNFfQojIEdlbmUgc2VsZWN0aW9uIGZvciBpbnB1dCB0byBDQ0EKRmluZFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MSwgCiAgICAgICAgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCB2ZXJib3NlID0gRkFMU0UpCkZpbmRWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IFNldXJhdDIsIAogICAgICAgIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCwgdmVyYm9zZSA9IEZBTFNFKQoKZXhwLmFuY2hvcnMgPC0gRmluZEludGVncmF0aW9uQW5jaG9ycyhvYmplY3QubGlzdCA9IGMoU2V1cmF0MixTZXVyYXQxKSwgZGltcyA9IDE6MzApCgpnZW5lMSA8LSByb3duYW1lcyhHZXRBc3NheURhdGEoU2V1cmF0MSwgYXNzYXkgPSAiUk5BIiwgc2xvdCA9ICJkYXRhIiApKQpnZW5lMiA8LSByb3duYW1lcyhHZXRBc3NheURhdGEoU2V1cmF0MiwgYXNzYXkgPSAiUk5BIiwgc2xvdCA9ICJkYXRhIiApKQpjb21tb25fZ2VuZXMgPC0gUmVkdWNlKGludGVyc2VjdCwgbGlzdChnZW5lMSxnZW5lMikpCgpleHAxLjIuaW50ZWdyYXRlZCA8LSBJbnRlZ3JhdGVEYXRhKGFuY2hvcnNldCA9IGV4cC5hbmNob3JzLCBmZWF0dXJlcy50by5pbnRlZ3JhdGUgPSBjb21tb25fZ2VuZXMsZGltcyA9IDE6MzApCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KV2UgaWRlbnRpZmllZCAqKmByIGxlbmd0aChnZW5lMSlgKiogZXhwcmVzc2VkIGluIHNhbXBsZTEgYW5kICoqYHIgbGVuZ3RoKGdlbmUyKWAqKiBleHByZXNzZWQgaW4gc2FtcGxlMi4gKipgciBsZW5ndGgoY29tbW9uX2dlbmVzKWAqKiBhcmUgaW4gY29tbW9uIGluIHRoaXMgdHdvIHNldCBhbmQgd2lsbCB0aGUgaW50ZWdyYXRlZCBpbiB0aGUgbWVyZ2VkIGFuZCBjb3JyZWN0ZWQgb2JqZWN0LgoKCiMjIFVNQVA6CgojIEFuYWx5c2lzIHBhcnQKCiMjIFNhbXBsZSBJbmZvcm1hdGlvbgoKVGhlIGFuYWx5c2lzIHdpbGwgYmUgcnVuIG9uIHRoZSBzYW1wbGUgTVlDX1BURU5fMDEgKDE4MTAzMSAmIDE5MDIxMSkuCgpEdXJpbmcgdGhlIHNhbXBsZSBsb2FkaW5nLCB3ZSBmaWx0ZXIgY2VsbHMgdGhhdCBkbyBub3QgcGFzcyB0aGUgZm9sbG93aW5nIGZpbHRlcnMuIFdlIGFsc28gZmlsdGVyIGNlbGxzIHRoYXQgYXJlIGRldGVjdGVkIGFzIGh1bWFuL21vdXNlIG11bHRpcGxldCB1c2luZyB0aGVpciBiYXJjb2Rlcy4gIApIZXJlIGFyZSB0aGUgZGVzY3JpcHRpb24gb2YgdGhvc2UgcGFyYW1ldGVycyBpbiB0aGUgU2V1cmF0ICpDcmVhdGVTZXVyYXRPYmplY3QqIGZ1bmN0aW9uOgoKKiBtaW4uZ2VuZXM6IEluY2x1ZGUgY2VsbHMgd2hlcmUgYXQgbGVhc3QgdGhpcyBtYW55IGdlbmVzIGFyZSBkZXRlY3RlZAoqIG1pbi5jZWxsczogSW5jbHVkZSBnZW5lcyB3aXRoIGRldGVjdGVkIGV4cHJlc3Npb24gaW4gYXQgbGVhc3QgdGhpcyBtYW55IGNlbGxzCgpgYGAKCmBgYHtyIGZpbHRlcnMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSxyZXN1bHRzPSdhc2lzJyxpbmNsdWRlPUZBTFNFfQojIEFmZmljaGUgbGVzIHBhcmFtZXRyZXMKRmlsdGVyX3BhcmFtZXRlcnMgPC0gZGF0YS5mcmFtZSgpCkZpbHRlcl9wYXJhbWV0ZXJzWyJWYWx1ZSIsICJtaW4uY2VsbHMiXSA8LSAzCkZpbHRlcl9wYXJhbWV0ZXJzWyJWYWx1ZSIsICJtaW4uZ2VuZXMiXSA8LSAyMDAKa2FibGUoRmlsdGVyX3BhcmFtZXRlcnMsICJodG1sIiwgYWxpZ24gPSAiYyIpICU+JSBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CkFmdGVyIHRob3NlIGZpbHRlcnMsIGFuZCBtZXJnaW5nIE1ZQ19QVEVOXzAxIGFuZCBNWUNfUFRFTjAyIHRoZSByZW1haW5pbmcgY2VsbCBudW1iZXIgaXMgKipgciBsZW5ndGgoY29sbmFtZXMoZXhwMS4yLmludGVncmF0ZWQpKWAqKi4KYGBgCgoKCmBgYHtyIGNlbGxfc2VsZWN0LGV2YWw9KHBhcnQyID09IFRSVUUgKSwgcmVzdWx0cz0nYXNpcycsaW5jbHVkZT1GQUxTRX0KIyMjIGFkZCBFeHAxIGNlbGwgaWRlbnRpdHkgKDE4MTAzMSkKI2FkZCBFeHAxIGNlbGwgaWRlbnRpdHkKSFRPX2NyNiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tY3RybCIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX2N0NiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtY3RybCIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX21yNiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tTSIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX210NiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTSIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3ByNiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tUCIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3B0NiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtUCIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3BtcjYgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcG10NiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTVAiICkpLCJfMiIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCgojIyMgYWRkIEV4cDIgY2VsbCBpZGVudGl0eSAoMTkwMjExKSAKSFRPX2NyMiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tY3RybCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX2N0MiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1jdHJsIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXIyIDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiU3BsZWVuLU0iICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19tdDIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtTSIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3ByMiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1QIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcHQyIDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiVGh5bXVzLVAiICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19wbXIyIDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiU3BsZWVuLU1QIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcG10MiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1NUCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKCgoKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhJEhUTyA9ICJub3RoaW5nIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX2NyMixdJEhUTyA9ICJXVCBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fY3QyLF0kSFRPID0gIldUIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19jcjYsXSRIVE8gPSAiV1Qgc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX2N0NixdJEhUTyA9ICJXVCB0aHltdXMiCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcHIyLF0kSFRPID0gIlBURU4tIHNwbGVlbiIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19wdDIsXSRIVE8gPSAiUFRFTi0gdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3ByNixdJEhUTyA9ICJQVEVOLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcHQ2LF0kSFRPID0gIlBURU4tIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19tcjIsXSRIVE8gPSAiTVlDLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fbXQyLF0kSFRPID0gIk1ZQy0gdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX21yNixdJEhUTyA9ICJNWUMtIHNwbGVlbiIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19tdDYsXSRIVE8gPSAiTVlDLSB0aHltdXMiCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcG1yMixdJEhUTyA9ICJNeWMtIFBURU4tIHNwbGVlbiIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19wbXQyLF0kSFRPID0gIk15Yy0gUFRFTi0gdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3BtcjYsXSRIVE8gPSAiTXljLSBQVEVOLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcG10NixdJEhUTyA9ICJNeWMtIFBURU4tIHRoeW11cyIKCkhUT190aHltdXMgPSBjKEhUT19jdDIsSFRPX210MixIVE9fcHQyLEhUT19wbXQyLEhUT19jdDYsSFRPX210NixIVE9fcHQ2LEhUT19wbXQ2KQpIVE9fc3BsZWVuID0gYyhIVE9fY3IyLEhUT19tcjIsSFRPX3ByMixIVE9fcG1yMixIVE9fY3I2LEhUT19tcjYsSFRPX3ByNixIVE9fcG1yNikKCmlkZW50aWZpZWQgPC0gYyhIVE9fdGh5bXVzLEhUT19zcGxlZW4pClZsblBsb3QoZXhwMS4yLmludGVncmF0ZWQsZmVhdHVyZXMgPSAibkZlYXR1cmVfUk5BIixwdC5zaXplID0gMC4xLCBsb2cgPSBUUlVFLCAgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpWbG5QbG90KGV4cDEuMi5pbnRlZ3JhdGVkLGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIkhUTyIpClZsblBsb3QoZXhwMS4yLmludGVncmF0ZWQsZmVhdHVyZXMgPSAibkZlYXR1cmVfUk5BIixwdC5zaXplID0gMC4xLCBsb2cgPSBUUlVFLCAgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCgpTZXVyYXQgPC0gZXhwMS4yLmludGVncmF0ZWQKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFVNQVAgYW5kIGNsdXN0ZXJpbmcgcGFyYW1ldGVyCmBgYAoKYGBge3IgU2lnbmlmaWNhbnRfUENfbWVyZ2UsIGV2YWw9KHBhcnQyID09IFRSVUUgKSxpbmNsdWRlPUZBTFNFfQojIFRyYWl0ZW1lbnQgZGUgbCdvYmpldAppZighIGZpbGUuZXhpc3RzKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdC1pbnRlZ3JhdGVkXzE4MTAzMV8xOTAyMTEuUm9iaiIpKSl7CiAgCiAgU2V1cmF0IDwtIFNjYWxlRGF0YSggb2JqZWN0ID0gIFNldXJhdCwgCiAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iaW50ZWdyYXRlZCIsCiAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAjZG8uc2NhbGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRvLmNlbnRlciA9IFRSVUUpCiAgCiAgU2V1cmF0IDwtIFJ1blBDQShvYmplY3QgPSBTZXVyYXQsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhTZXVyYXQpLCBucGNzID0gNTAsIHNlZWQudXNlID0gMTIzNCwgdmVyYm9zZSA9IEZBTFNFKQogIAogIEVsYm93UGxvdChTZXVyYXQsIG5kaW1zID0gNDAsIHJlZHVjdGlvbiA9ICJwY2EiKQogIAogICMgU2NvcmVyIGxlcyBnZW5lcyBwb3VyIGxlcyBjb21wb3NhbnRlcwogIFNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFNldXJhdCwKICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTIpCiAgCiAgU2V1cmF0IDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gU2V1cmF0LCAKICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MTIgLCAKICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UpIywgCiAgICAgICAgICAgICAgICAgICNmb3JjZS5yZWNhbGMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgI3JlZHVjdGlvbiA9ICJwY2EiKQogIAogIFNldXJhdCA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gU2V1cmF0LCAKICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbiA9IDEsCiAgICAgICAgICAgICAgICAgIGFzc2F5PSJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgICAKICAjVG8gbWFrZSB0aGUgVU1BUAogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiAgU2V1cmF0IDwtIFJ1blVNQVAob2JqZWN0ID0gU2V1cmF0LCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToxMikKICAKICBEaW1QbG90KG9iamVjdCA9IFNldXJhdCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikKICAKICBzYXZlKFNldXJhdCwgZmlsZSA9IHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdC1pbnRlZ3JhdGVkXzE4MTAzMV8xOTAyMTEuUm9iaiIpKQp9ZWxzZXsKICBsb2FkKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdC1pbnRlZ3JhdGVkXzE4MTAzMV8xOTAyMTEuUm9iaiIpKQp9CmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgTWVyZ2UgY2hlY2tpbmcgey50YWJzZXR9CiMjIyBIVE8KYGBgCgpgYGB7cixldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89RkFMU0V9CmdncGxvdGx5KERpbVBsb3QoU2V1cmF0LCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gIkhUTyIsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDEpKwogICAgICAgICAgIGdndGl0bGUoIlVNQVAgY29sb3JyZWQgYnkgSFRPIGNsYXNzaWZpY2F0aW9uIikpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgT3JpZy5pZGVudHMKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGVjaG89RkFMU0V9CmdncGxvdGx5KERpbVBsb3QoU2V1cmF0LCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCBkby5sYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAxKSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBULWNlbGwgc2VsZWN0aW9uIHsudGFic2V0fQpBY2NvcmRpbmcgdG8gVC1jZWxsIG1hcmtlcnMgd2Ugd2lsbCBleGNsdWRlIENkM2QgbG93IGNsdXN0ZXJzOiAxMyAoQmNlbGxzKSwgMTEsIDE0LCAxNyAobW9ub2N5dGVzL21hY3JvcGhhZ2VzKS4KQWNjb3JkaW5nIHRvIFQtY2VsbCBtYXJrZXJzIHdlIHdpbGwgZXhjbHVkZSBDZDNkL0NkM2UgbG93IGNsdXN0ZXJzOiAxMSAoQmNlbGxzKSwgMTMsIDE3LCAxOCwgMTkgKG1vbm9jeXRlcy9tYWNyb3BoYWdlcyksIDE2LCAxNCAoSUxDL05LKS4KCiMjIyBLbm93biBSTkEgQiBhbmQgVCBtYXJrZXJzCmBgYAoKYGBge3IgYnRfbWFya2Vyc19jaGVja2luZywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPUZBTFNFfQpEaW1QbG90KFNldXJhdCwgbGFiZWwgPSBUKQpiY2VsbF9rbm93bl9tYXJrZXJzIDwtIGMoIkNkNzQiLCJNczRhMSIsIkNkMTkiLCJDZDNkIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IGJjZWxsX2tub3duX21hcmtlcnMsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgIGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKYmNlbGxfa25vd25fbWFya2VycyA8LSBjKCJDZDE0IiwiRmNncjMiLCJUcmRjIiwiQ2QzZCIpCkZlYXR1cmVQbG90KG9iamVjdCA9IFNldXJhdCwgZmVhdHVyZXMgPSBiY2VsbF9rbm93bl9tYXJrZXJzLCByZWR1Y3Rpb24gPSAidW1hcCIsICBjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCkZlYXR1cmVQbG90KG9iamVjdCA9IFNldXJhdCwgZmVhdHVyZXMgPSBjKCJJbDJyYSIsIktscmcxIiwiSWw3ciIsIlJvcmEiKSwgcmVkdWN0aW9uID0gInVtYXAiLCBvcmRlciA9IFRSVUUsIGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IGMoIkVvbWVzIiwiTmNyMSIsIlRieDIxIiwiS2l0IiksIHJlZHVjdGlvbiA9ICJ1bWFwIiwgb3JkZXIgPSBUUlVFLCBjb2xzID0gYygiZ3JleSIsICJsaWdodCBibHVlIiwiY3lhbjMiLCJjeWFuNCIsImRvZGdlcmJsdWUzIiwiYmx1ZSIsIm1lZGl1bXNsYXRlYmx1ZSIsInB1cnBsZSIsIm9yY2hpZDMiLCJyZWQiLCJicm93biIsImJsYWNrIikpCiNOcmMxID0gTksKI0lMN1IgdG8gc2VwYXJhdGUgSUxDIGZyb20gTks7IElMN1IrIEVPTUVTKyBzaG91bGQgYmUgSUxDMTsgRU9NRVMrIElMN1ItIHNob3VsZCBiZSBOSwoKI2NvbXBhcmlzb24gYmV0d2VlbiBtYXJrZXIgYW5kIGNsdXN0ZXIgcG9zaXRpb24KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkpCmBgYAoKYGBge3IgVGNlbGxfc2VsZWN0aW9uLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KI3JlbW92ZSBjbHVzdGVyIDExLDEyLDEzLDE3ICgjQmNlbGxzICYgbWFjcm9waGFnZXMpClQuU2V1cmF0IDwtIHN1YnNldCh4ID0gU2V1cmF0LCBpZGVudHMgPSBjKCIxMSIsIjEzIiwiMTQiLCIxNiIsIjE3IiwiMTgiLCIxOSIpLCBpbnZlcnQgPSBUUlVFKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgcmUgY2x1c3RlcmluZwpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFLCBldmFsPShwYXJ0MiA9PSBUUlVFICl9CiMgVHJhaXRlbWVudCBkZSBsJ29iamV0CmlmKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldF8iLCAiLlJvYmoiKSkpewogICMgU2VsZWN0aW9uIHdhcyBhbHJlYWR5IGRvbmUgYXQgdGhlIGludGVncmF0aW9uIHN0ZXAsIGV2ZW4gYWZ0ZXIgcmVzdWJzZXR0aW5nIGl0IGlzIHdvcnRoIHRvIHJlc2VsZWN0IChodHRwczovL2dpdGh1Yi5jb20vc2F0aWphbGFiL3NldXJhdC9pc3N1ZXMvMTUyOCkuIFJOQSBzaG91bGQgYmUgdXNlZCwgYnV0IHRoZW4gYmF0Y2ggaXMgYmFjaywgc3Vic2V0dGluZyBiZWZvcmUgaW50ZWdyYXRpb24gaXMgbm90IGdvb2QgbmVpdGhlciAoYmV0dGVyIHRvIGtlZXAgY2VsbHMgdGhhdCBjYW4gYmUgYWxpZ25lZCkuLi4gCiAgCiAgVC5TZXVyYXQgPC0gU2NhbGVEYXRhKCBvYmplY3QgPSAgVC5TZXVyYXQsIAogICAgICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgI2RvLnNjYWxlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQogIAogIFQuU2V1cmF0IDwtIFJ1blBDQShvYmplY3QgPSBULlNldXJhdCwgZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKFQuU2V1cmF0KSwgbnBjcyA9IDEwMCwgc2VlZC51c2UgPSAxMjM0LCB2ZXJib3NlID0gRkFMU0UpCiAgCiAgRWxib3dQbG90KFQuU2V1cmF0LCBuZGltcyA9IDUwLCByZWR1Y3Rpb24gPSAicGNhIikKICAKICAjIFNjb3JlciBsZXMgZ2VuZXMgcG91ciBsZXMgY29tcG9zYW50ZXMKICBULlNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFQuU2V1cmF0LAogICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCiAgCiAgVC5TZXVyYXQgPC0gRmluZE5laWdoYm9ycyhvYmplY3QgPSBULlNldXJhdCwKICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiaW50ZWdyYXRlZCIsCiAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjE4ICwgCiAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSkjLCAKICAgICAgICAgICAgICAgICAgI2ZvcmNlLnJlY2FsYyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAjcmVkdWN0aW9uID0gInBjYSIpCiAgCiAgICBULlNldXJhdCA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gVC5TZXVyYXQsIAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbiA9IDEuOCwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgI1RvIG1ha2UgdGhlIFVNQVAKICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwogIFQuU2V1cmF0IDwtIFJ1blVNQVAob2JqZWN0ID0gVC5TZXVyYXQsIHJlZHVjdGlvbiA9ICJwY2EiLCBzZWVkLnVzZSA9IDEyMzQsIGRpbXMgPSAxOjE4KQogIAogIERpbVBsb3Qob2JqZWN0ID0gVC5TZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCiAgcDEgPC0gRGltUGxvdChvYmplY3QgPSBULlNldXJhdCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikKICBwMiA8LSBEaW1QbG90KG9iamVjdCA9IFQuU2V1cmF0LCByZWR1Y3Rpb24gPSAicGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIAogICAgICBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVFJVRSkgKyBOb0xlZ2VuZCgpCiAgCiAgZ3JpZC5hcnJhbmdlKHAxLHAyLG5yb3cgPSAxLCBuY29sID0yLCBuZXdwYWdlPVRSVUUpCgogIHNhdmUoVC5TZXVyYXQsIGZpbGUgPSBwYXN0ZTAoT1VUUFVUX1BBVEgsICJULVNldXJhdC1tZXJnZWRfY2xlYW4tc3Vic2V0IiwgIi5Sb2JqIikpCn1lbHNlewogIGxvYWQocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldCIsICIuUm9iaiIpKQp9CgpgYGAKCmBgYHtyICwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGVjaG89RkFMU0V9CiMjIyBhZGQgRXhwMiBjZWxsIGlkZW50aXR5ICgxOTAyMTEpIApzcGxlZW4uY2VsbHMgPC0gYyhyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgKSkscm93Lm5hbWVzKHN1YnNldChULlNldXJhdEBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tUCIgKSkpCgp0aHltdXMuY2VsbHMgPC0gYyhyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1jdHJsIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NUCIgKSkscm93Lm5hbWVzKHN1YnNldChULlNldXJhdEBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtUCIgKSkpCgpULlNldXJhdEBtZXRhLmRhdGEkdGlzc3VlID0gIm5vdGhpbmciClQuU2V1cmF0QG1ldGEuZGF0YVtzcGxlZW4uY2VsbHMsXSR0aXNzdWUgPSAiU3BsZWVuIgpULlNldXJhdEBtZXRhLmRhdGFbdGh5bXVzLmNlbGxzLF0kdGlzc3VlID0gIlRoeW11cyIKCkRpbVBsb3QoVC5TZXVyYXQpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgVC1jZWxsIHVtYXBzIHsudGFic2V0fQojIyMgSFRPCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQyID09IFRSVUUgKSxlY2hvPUZBTFNFfQpnZ3Bsb3RseShEaW1QbG90KFQuU2V1cmF0LCBncm91cC5ieSA9ICJNVUxUSV9JRCIpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBjbHVzdGVyaW5nCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQyID09IFRSVUUgKSxlY2hvPUZBTFNFfQooRGltUGxvdChULlNldXJhdCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJpbnRlZ3JhdGVkX3Nubl9yZXMuMS44IiwgbGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgRU5EIE9GIFBSRVBST0NFU1NJTkcKV2Ugb2J0YWluIHRoZSBmaW5hbCBvYmplY3Qgd2l0aCBjbHVzdGVyaW5nIHRvIHN0YXJ0IHRoZSBhbmFseXNpcwpgYGAKCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoK